Thread: DirectX | Drawing text

  1. #1
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265

    DirectX | Drawing text

    simple text drawing:

    Code:
    void PrintText(char* str, int size, int x, int y, DWORD color)
    {
    	static RECT textbox;
    	SetRect(&textbox, x, y, SCREEN_WIDTH, SCREEN_HEIGHT);
    	D3DXCreateFont(d3ddev,    // the D3D Device
                       size,    // font height
                       0,    // default font width
                       FW_NORMAL,    // font weight
                       1,    // not using MipLevels
                       false,    // italic font
                       DEFAULT_CHARSET,    // default character set
                       OUT_DEFAULT_PRECIS,    // default OutputPrecision,
                       DEFAULT_QUALITY,    // default Quality
                       DEFAULT_PITCH | FF_DONTCARE,    // default pitch and family
                       "Arial",    // use Facename Arial
                       &dxfont);    // the font object
        dxfont->DrawTextA(NULL,
                          str,
                          strlen(str),
                          &textbox,
                          DT_LEFT | DT_TOP,
                          color);
    }
    When I draw some text many times in the main loop it makes the whole window slower.. why? \=
    gavra.

  2. #2
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Not a D3D guy, but if I had to guess I would say that calling D3DXCreateFont() consecutively in a main loop is what's slowing it down. Create the font in your initialisation stage, and just access the pointer to actually draw the text in your main loop.
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  3. #3
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    I guess so too but how do I set again the size and the location?
    gavra.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    ID3DXFont has a function called DrawText() that allows you to set the positioning and color of the text. If you want on-the-fly size you will have to write your own class or get a hold of Microsoft's CD3DFont class.

    Reading the SDK usually helps a lot. How do you people program in Direct3D or in any API without having the reference to it?



    D3DXCreateFont
    Creates a font object for a device and font.

    HRESULT D3DXCreateFont(
    LPDIRECT3DDEVICE9 pDevice,
    INT Height,
    UINT Width,
    UINT Weight,
    UINT MipLevels,
    BOOL Italic,
    DWORD CharSet,
    DWORD OutputPrecision,
    DWORD Quality,
    DWORD PitchAndFamily,
    LPCTSTR pFacename,
    LPD3DXFONT * ppFont
    );
    Parameters
    pDevice
    [in] Pointer to an IDirect3DDevice9 interface, the device to be associated with the font object.
    Height
    [in] The height of the characters in logical units.
    Width
    [in] The width of the characters in logical units.
    Weight
    [in] Typeface weight. One example is bold.
    MipLevels
    [in] The number of mipmap levels.
    Italic
    [in] True for italic font, false otherwise.
    CharSet
    [in] The character set of the font.
    OutputPrecision
    [in] Specifies how Windows should attempt to match the desired font sizes and characteristics with actual fonts. Use OUT_TT_ONLY_PRECIS for instance, to ensure that you always get a TrueType font.
    Quality
    [in] Specifies how Windows should match the desired font with a real font. It applies to raster fonts only and should not affect TrueType fonts.
    PitchAndFamily
    [in] Pitch and family index.
    pFacename
    [in] String containing the typeface name. If the compiler settings require Unicode, the data type LPCTSTR resolves to LPCWSTR. Otherwise, the string data type resolves to LPCSTR. See Remarks.
    ppFont
    [out] Returns a pointer to an ID3DXFont interface, representing the created font object.
    Return Values
    If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the following: D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY.

    Remarks
    The creation of an ID3DXFont object requires that the device supports 32-bit color.

    The compiler setting also determines the function version. If Unicode is defined, the function call resolves to D3DXCreateFontW. Otherwise, the function call resolves to D3DXCreateFontA because ANSI strings are being used.

    If you want more information about font parameters, see The Logical Font.

    Requirements
    Header: Declared in D3dx9core.h.
    And looking up ID3DXFont which is what D3DXCreateFont clearly returns on the stack:

    ID3DXFont
    The ID3DXFont interface encapsulates the textures and resources needed to render a specific font on a specific device.

    ID3DXFont Members
    Method Description
    ID3DXFont::DrawText Draws formatted text. This method supports ANSI and Unicode strings.
    ID3DXFont::GetDC Returns a handle to a display device context (DC) that has the font set.
    ID3DXFont::GetDesc Gets a description of the current font object. GetDescW and GetDescA are identical to this method, except that a pointer is returned to a D3DXFONT_DESCD3DXFONT_DESCW
    ID3DXFont::GetDevice Retrieves the Direct3D device associated with the font object.
    ID3DXFont::GetGlyphData Returns information about the placement and orientation of a glyph in a character cell.
    ID3DXFont::GetTextMetrics Retrieves font characteristics that are identified in a TEXTMETRIC structure. This method supports ANSI and Unicode compiler settings.
    ID3DXFont::OnLostDevice Use this method to release all references to video memory resources and delete all stateblocks. This method should be called whenever a device is lost, or before resetting a device.
    ID3DXFont::OnResetDevice Use this method to re-acquire resources and save initial state.
    ID3DXFont::PreloadCharacters Loads a series of characters into video memory to improve the efficiency of rendering to the device.
    ID3DXFont::PreloadGlyphs Loads a series of glyphs into video memory to improve the efficiency of rendering to the device.
    ID3DXFont::PreloadText Loads formatted text into video memory to improve the efficiency of rendering to the device. This method supports ANSI and Unicode strings.

    Remarks
    The ID3DXFont interface is obtained by calling D3DXCreateFont or D3DXCreateFontIndirect.

    The LPD3DXFONT type is defined as a pointer to the ID3DXFont interface.

    typedef interface ID3DXFont ID3DXFont;
    typedef interface ID3DXFont *LPD3DXFONT;

    Requirements
    Header: Declared in D3dx9core.h.

    Library: Use D3dx9.lib.
    And looking up ID3DXFont::DrawText():

    ID3DXFont::DrawText
    Draws formatted text. This method supports ANSI and Unicode strings.

    INT DrawText(
    LPD3DXSPRITE pSprite,
    LPCTSTR pString,
    INT Count,
    LPRECT pRect,
    DWORD Format,
    D3DCOLOR Color
    );
    Parameters
    pSprite
    [in] Pointer to an ID3DXSprite object that contains the string. Can be NULL, in which case Direct3D will render the string with its own sprite object. To improve efficiency, a sprite object should be specified if ID3DXFont::DrawText is to be called more than once in a row.
    pString
    [in] Pointer to a string to draw.If the Count parameter is -1, the string must be null-terminated.
    Count
    [in] Specifies the number of characters in the string. If Count is -1, then the pString parameter is assumed to be a pointer to a null-terminated string and ID3DXFont::DrawText computes the character count automatically.
    pRect
    [in] Pointer to a RECT structure that contains the rectangle, in logical coordinates, in which the text is to be formatted. As with any RECT object, the coordinate value of the rectangle's right side must be greater than that of its left side. Likewise, the coordinate value of the bottom must be greater than that of the top.
    Format
    [in] Specifies the method of formatting the text. It can be any combination of the following values:
    DT_BOTTOM
    Justifies the text to the bottom of the rectangle. This value must be combined with DT_SINGLELINE.
    DT_CALCRECT
    Determines the width and height of the rectangle. If there are multiple lines of text, ID3DXFont::DrawText uses the width of the rectangle pointed to by the pRect parameter and extends the base of the rectangle to bound the last line of text. If there is only one line of text, ID3DXFont::DrawText modifies the right side of the rectangle so that it bounds the last character in the line. In either case, ID3DXFont::DrawText returns the height of the formatted text but does not draw the text.
    DT_CENTER
    Centers text horizontally in the rectangle.
    DT_EXPANDTABS
    Expands tab characters. The default number of characters per tab is eight.
    DT_LEFT
    Aligns text to the left.
    DT_NOCLIP
    Draws without clipping. ID3DXFont::DrawText is somewhat faster when DT_NOCLIP is used.
    DT_RIGHT
    Aligns text to the right.
    DT_RTLREADING
    Displays text in right-to-left reading order for bidirectional text when a Hebrew or Arabic font is selected. The default reading order for all text is left-to-right.
    DT_SINGLELINE
    Displays text on a single line only. Carriage returns and line feeds do not break the line.
    DT_TOP
    Top-justifies text.
    DT_VCENTER
    Centers text vertically (single line only).
    DT_WORDBREAK
    Breaks words. Lines are automatically broken between words if a word would extend past the edge of the rectangle specified by the pRect parameter. A carriage return/line feed sequence also breaks the line.
    Color
    [in] Color of the text. For more information, see D3DCOLOR.
    Return Values
    If the function succeeds, the return value is the height of the text in logical units. If DT_VCENTER or DT_BOTTOM is specified, the return value is the offset from pRect (top to the bottom) of the drawn text. If the function fails, the return value is zero.

    Remarks
    The parameters of this method are very similar to those of the GDI DrawText function.

    This method supports both ANSI and Unicode strings.

    This method must be called inside a IDirect3DDevice9::BeginScene ... IDirect3DDevice9::EndScene block. The only exception is when an application calls ID3DXFont::DrawText with DT_CALCRECT to calculate the size of a given block of text.

    Unless the DT_NOCLIP format is used, this method clips the text so that it does not appear outside the specified rectangle. All formatting is assumed to have multiple lines unless the DT_SINGLELINE format is specified.

    If the selected font is too large for the rectangle, this method does not attempt to substitute a smaller font.

    This method supports only fonts whose escapement and orientation are both zero.

    Requirements
    Header: Declared in D3dx9core.h.
    Seems pretty straight-forward to me. 3 mouse clicks in the SDK and your question is answered. Also you should create the font ONCE and then re-use it. Creating the font once every frame is going to be horribly slow.
    Last edited by VirtualAce; 06-07-2009 at 01:21 PM.

  5. #5
    Registered User gavra's Avatar
    Join Date
    Jun 2008
    Posts
    265
    ok very nice, thank you.
    humm but one thing that I don't understand is how I can re-set the size (?..)
    (I didn't get the idea of using a class)
    am I supposed to re-load the font?
    Last edited by gavra; 06-08-2009 at 12:40 AM.
    gavra.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. DirectX | Simple Drawing
    By gavra in forum Game Programming
    Replies: 8
    Last Post: 05-31-2009, 05:17 PM
  2. How to use FTP?
    By maxorator in forum C++ Programming
    Replies: 8
    Last Post: 11-04-2005, 03:17 PM
  3. Drawing Test with Raster Op
    By genghis in forum Windows Programming
    Replies: 0
    Last Post: 07-02-2004, 12:21 AM
  4. Replies: 1
    Last Post: 07-13-2002, 05:45 PM
  5. displaying text with DirectX
    By MechanicX in forum Game Programming
    Replies: 4
    Last Post: 09-24-2001, 06:28 PM